@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)

import kotlinx.cinterop.*
import kotlin.native.concurrent.*
import platform.posix.*
import kotlin.collections.LinkedHashMap
import kotlin.text.Regex

object regexredux {
    // 替换规则（保持顺序并冻结）
    private val replacements = LinkedHashMap<String, String>().apply {
        put("tHa[Nt]", "<4>")
        put("aND|caN|Ha[DS]|WaS", "<3>")
        put("a[NSt]|BY", "<2>")
        put("<[^>]*>", "|")
        put("\\|[^|][^|]*\\|", "-")
    }.freeze()

    fun run(args: Array<String>) {
        // 读取dna.txt文件内容
        val input = readFile("dna.txt")
        val initialLength = input.length

        // 生成序列：移除>开头的行和所有换行符
        val sequence = input.replace(">.*\n|\n".toRegex(), "").freeze()
        val codeLength = sequence.length

        // 定义需要匹配的正则变体
        val variants = arrayOf(
            "agggtaaa|tttaccct",
            "[cgt]gggtaaa|tttaccc[acg]",
            "a[act]ggtaaa|tttacc[agt]t",
            "ag[act]gtaaa|tttac[agt]ct",
            "agg[act]taaa|ttta[agt]cct",
            "aggg[acg]aaa|ttt[cgt]ccct",
            "agggt[cgt]aa|tt[acg]accct",
            "agggta[cgt]a|t[acg]taccct",
            "agggtaa[cgt]|[acg]ttaccct"
        ).freeze()

        // 使用线程池处理正则匹配（复用Worker）
        val nCpu = 4 // 手动指定CPU核心数
        val workers = List(nCpu) { Worker.start() }
        val futures = mutableListOf<Future<Int>>()

        // 分配任务到Worker
        variants.forEachIndexed { index, variant ->
            val worker = workers[index % nCpu] // 轮询分配任务
            futures.add(
                worker.execute(TransferMode.SAFE, { Pair(variant, sequence) }) { (v, s) ->
                    Regex(v).findAll(s).count()
                }
            )
        }

        // 收集匹配结果
        val results = IntArray(variants.size)
        futures.forEachIndexed { i, future ->
            results[i] = future.result
        }

        // 输出匹配结果（按原始顺序）
        variants.forEachIndexed { i, variant ->
            println("$variant ${results[i]}")
        }

        // 执行替换操作
        var buf = sequence
        replacements.forEach { (regex, replacement) ->
            buf = Regex(regex).replace(buf, replacement)
        }

        // 输出长度信息
        println()
        println(initialLength)
        println(codeLength)
        println(buf.length)

        // 清理Worker资源
        workers.forEach { it.requestTermination() }
    }

    // 读取文件内容（Kotlin/Native文件IO）
    private fun readFile(filename: String): String {
        val file = fopen(filename, "r") ?: error("无法打开文件: $filename")
        return try {
            val buffer = ByteArray(4096)
            val content = StringBuilder()
            memScoped {
                while (true) {
                    val bytesRead = fread(
                        buffer.refTo(0),
                        1UL,
                        buffer.size.toULong(),
                        file
                    ).toInt()
                    if (bytesRead <= 0) break
                    content.append(buffer.decodeToString(0, bytesRead))
                }
            }
            content.toString()
        } finally {
            fclose(file)
        }
    }
}

// 程序入口
fun main(args: Array<String>) = regexredux.run(args)